#include "record.h"
#include "utils.h"
#include <QDateTime>
#include <QUuid>

QString Record::localMac = "";

Record::Record(QObject *parent)
    : QObject{parent}
{
    HadWarnning = false;
}


Record* Record::FromJson(QJsonObject &data){
    auto info = new Record();
    info->CreateTime = GetString(data, "createTime");
    info->DateCount = GetInt(data, "dateCount");
    info->DateUnit = GetInt(data, "dateUnit");
    info->Deleted = GetInt(data, "deleted");
    info->HasPart = GetInt(data, "hasPart");
    info->HasWarn = GetInt(data, "hasWarn");
    info->LocalId = GetString(data, "localId");
    info->RecordId = GetInt(data, "recordId");
    info->MakeAt = GetInt(data, "makeAt");
    info->Name = GetString(data, "name");
    info->OperationType = GetInt(data, "operationType");
    info->PId = GetString(data, "pId");
    info->PartCount = GetInt(data, "partCount");
    info->PartUnit = GetInt(data, "partUnit");
    info->Remark = GetString(data, "remark");
    info->SaveType = GetInt(data, "saveType");
    info->ShopCode = GetString(data, "shopCode");
    info->ShortName = GetString(data, "shortName");
    info->Status = GetInt(data, "stauts");
    info->TemplateId = GetInt(data, "templateId");
    info->TypeName = GetString(data, "typeName");
    info->Unit = GetInt(data, "unit");
    info->UpdateTime = GetString(data, "updateTime");
    info->VailAt = GetInt(data, "vailAt");
    info->WarnCount = GetInt(data, "warnCount");
    info->WarnUnit = GetInt(data, "warnUnit");

    return info;
}

int Record::computeVailAt(int unit, int count) {
    QDateTime future;
    QDateTime now = QDateTime::currentDateTime();
    switch (unit) {
    case SVT_HOUR:
        future = now.addSecs(count * 60 * 60);
        break;
    case SVT_DATE:
        future = now.addDays(count);
        // future.setTime(QTime(23, 59, 59, 999));
        break;
    case SVT_WEEK:
    {
        QDate currentDate = QDate::currentDate();
        int currentDayOfWeek = currentDate.dayOfWeek();
        int daysToAdd = (7 - currentDayOfWeek) % 7;
        QDate targetDate = currentDate.addDays(daysToAdd);
        future = QDateTime(targetDate, QTime(23, 59, 59, 999));
    }
    break;
    case SVT_MOUNTH:{
        QDate currentDate = QDate::currentDate();
        QDate endOfMonth = currentDate.addMonths(1).addDays(-currentDate.day());
        future = QDateTime(endOfMonth, QTime(23, 59, 59, 999));
    }
    break;
    case SVT_CLOSE:
        future = now;
        future.setTime(QTime(23, 59, 59, 999));
        break;
    case SVT_PRIORITY:
        future = now;
        break;
    default:
        future = now;
        break;
    }
    return future.toSecsSinceEpoch();
}

Record* Record::FromMaterial(Material* m, QString shopCode){
    QUuid uuid = QUuid::createUuid();
    qint64 timestampSec = QDateTime::currentSecsSinceEpoch();
    auto info = new Record();
    info->CreateTime = "";
    info->DateCount = m->DateCount;
    info->DateUnit = m->DateUnit;
    info->Deleted = 0;
    info->HasPart = m->HasPart;
    info->HasWarn = m->HasWarn;
    info->LocalId = localMac + uuid.toString();
    info->RecordId = -1;
    info->MakeAt = timestampSec;
    info->Name = m->Name;
    info->OperationType = m->OperationType;
    info->PId = "";
    info->PartCount = m->PartCount;
    info->PartUnit = m->PartUnit;
    info->Remark = m->Remark;
    info->SaveType = m->SaveType;
    info->ShopCode = shopCode;
    info->ShortName = m->ShortName;
    info->Status = m->Status;
    info->TemplateId = m->Id;
    info->TypeName = m->TypeName;
    info->Unit = m->Unit;
    info->UpdateTime = timestampSec;
    info->VailAt = info->computeVailAt(info->DateUnit, info->DateCount);
    info->WarnCount = m->WarnCount;
    info->WarnUnit = m->WarnUnit;

    return info;
}

Record* Record::FromParent(Record* parent, QString shopCode){
    QUuid uuid = QUuid::createUuid();
    qint64 timestampSec = QDateTime::currentDateTime().toSecsSinceEpoch();
    auto info = new Record();
    info->CreateTime = "";
    info->DateCount = parent->PartCount;
    info->DateUnit = parent->PartUnit;
    info->Deleted = 0;
    info->HasPart = 0;
    info->HasWarn = parent->HasWarn;
    info->LocalId = localMac + uuid.toString();
    info->RecordId = -1;
    info->MakeAt = timestampSec;
    info->Name = parent->Name + "(分装)";
    info->OperationType = parent->OperationType;
    info->PId = parent->LocalId;
    info->PartCount = parent->PartCount;
    info->PartUnit = parent->PartUnit;
    info->Remark = parent->Remark;
    info->SaveType = parent->SaveType;
    info->ShopCode = shopCode;
    info->ShortName = parent->ShortName;
    info->Status = parent->Status;
    info->TemplateId = parent->TemplateId;
    info->TypeName = parent->TypeName;
    info->Unit = parent->Unit;
    info->UpdateTime = timestampSec;
    int vailAt = info->computeVailAt(info->PartUnit, info->PartCount);
    qDebug()<<"new:" << vailAt << " | parent: " << parent->VailAt;
    info->VailAt = vailAt > parent->VailAt ? parent->VailAt : vailAt;
    info->WarnCount = parent->WarnCount;
    info->WarnUnit = parent->WarnUnit;

    return info;
}

QString Record::GetMakeTimeString() {
    QDateTime makeTime = QDateTime::fromSecsSinceEpoch(MakeAt);
    return makeTime.toString("yyyy年MM月dd日 HH:mm:ss");
}

QString Record::GetValidityTimeString(){
    switch (this->DateUnit) {
    case SVT_HOUR:
    case SVT_DATE:
    case SVT_MOUNTH:
    {
        QDateTime vailTime = QDateTime::fromSecsSinceEpoch(VailAt);
        return vailTime.toString("yyyy年MM月dd日 HH:mm:ss");
    }
    case SVT_WEEK:
    case SVT_CLOSE:
    {
        QDateTime vailTime = QDateTime::fromSecsSinceEpoch(VailAt);
        return vailTime.toString("yyyy年MM月dd日 ddd 打烊");
    }
    case SVT_PRIORITY:
        return "下次优先使用";
    default:
        return "无";
    }
}

QString Record::GetSaveTypeString(){
    switch(SaveType) {
    case 1:
        return "冷冻";
    case 2:
        return "冷藏";
    case 3:
        return "常温";
    case 10:
        return "其它";
    default:
        return "未知";
    }
}

QJsonObject Record::ToJson(){
    QJsonObject obj;
    obj["localId"] = LocalId;
    obj["recordId"] = -1;
    obj["pId"] = PId;
    obj["shopCode"] = ShopCode;
    obj["makeAt"] = MakeAt;
    obj["vailAt"] = VailAt;
    obj["templateId"] = TemplateId;
    obj["name"] = Name;
    obj["shortName"] = ShortName;
    obj["unit"] = Unit;
    obj["saveType"] = SaveType;
    obj["operationType"] = OperationType;
    obj["dateUnit"] = DateUnit;
    obj["dateCount"] = DateCount;
    obj["hasWarn"] = HasWarn;
    obj["warnCount"] = WarnCount;
    obj["warnUnit"] = WarnUnit;
    obj["hasPart"] = HasPart;
    obj["partCount"] = PartCount;
    obj["partUnit"] = PartUnit;
    obj["remark"] = Remark;
    obj["createdAt"] = "";
    obj["typeName"] = TypeName;
    obj["deleted"] = Deleted;
    return obj;
}

bool Record::isExpired(){
    QDateTime now = QDateTime::currentDateTime();
    QDateTime vailTime = QDateTime::fromSecsSinceEpoch(VailAt);
    return now >= vailTime;
}

bool Record::isExpiring(){
    int beforeTime = 0;
    if (!HasWarn) {
        return false;
    }
    switch (WarnUnit) {
    case 1:
        beforeTime = WarnCount * 60;
        break;
    case 2:
        beforeTime = WarnCount * 60 * 60;
        break;
    case 3:
        beforeTime = WarnCount * 24 *60 * 60;
    case 10:
    default:
        return false;
    }

    int restTime = VailAt - QDateTime::currentSecsSinceEpoch();


    if (restTime > 0 &&  restTime <= beforeTime) {
        return true;
    }
    return false;
}

void Record::Delete(){
    Deleted = QDateTime::currentSecsSinceEpoch();
}

QString Record::GetStatusString(){
    if (isExpired()) {
        return "已过期";
    }
    if (isExpiring()) {
        return "即将过期";
    }
    return "有效中";
}
